package main;

import entitaet.*;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;


public class DAO {
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("KBSE08"); 
    EntityManager em  = emf.createEntityManager();

    
    private void persist(Object c) {
        em.getTransaction().begin();
        try {
            em.persist(c);
            em.getTransaction().commit();
        } catch(Exception e) {
            System.err.println("### Fehler: " + e.getMessage());
        } 
    }
    
    
    
    public void produktAnlegen(String pname, int vk) {
        Produkt p = new Produkt(pname, vk);
        persist(p);
    }

    public void bestellungAnlegen(String kunde) {
        Bestellung b = new Bestellung(kunde);
        persist(b);
    }

    
    // ERGÄNZEN
    public void produktInBestellungErgaenzen(int bst, int pn, int anz) {
        Bestellung b = em.find(Bestellung.class, bst);
        if(b == null) {
            System.out.println("### Fehler: Bestellung mit der ID " + bst + " nicht vorhanden");
        }
        else {
            Produkt p = em.find(Produkt.class, pn);
            if(p == null) {
                System.out.println("### Fehler: Produkt mit der ID " + pn + " nicht vorhanden");
            }
            else {
                Posten posten = new Posten(b, pn, anz);
                persist(posten);
                em.getTransaction().begin();
                b.addPosten(posten);
                em.getTransaction().commit(); 
            } 
        }
    }
    
    

    public void produktAusBestellungLoeschen(int bstnr, int pnr) {
        Bestellung b = em.find(Bestellung.class, bstnr);
        Posten p     = em.find(Posten.class, pnr);
        if(b == null) {
            System.out.println("### Fehler: Bestellung mit der ID " + bstnr + " nicht vorhanden");
        }
        else if(p == null){
                System.out.println("### Fehler: Posten mit der ID " + pnr + " nicht vorhanden");
        }
        else{
            em.getTransaction().begin();
            b.removePosten(p);
            em.remove(p);
            em.getTransaction().commit();               
         
        }  
    }

    
    
    public void produkteAnzeigen() {
        for(Produkt p : em.createQuery("SELECT p FROM Produkt p", Produkt.class).getResultList()) {
            System.out.println( p );
        }
    }

    public void bestellungenAnzeigen() {
        for(Bestellung b : em.createQuery("SELECT b FROM Bestellung b", Bestellung.class).getResultList()) {
            System.out.println( b );
        }
    }

    
    // o.getClass().getName().equals("[Ljava.lang.Object;")) ???
    public void produktbestellungshaeufigkeiten() {
        String s ="SELECT SUM(p.poAnzahl), p.prId FROM Posten p GROUP BY p.prId";
        
        try {
            Query query = em.createQuery(s);
            Collection result = query.getResultList();
            
            Iterator it = result.iterator();
            while( it.hasNext() ){
                Object o = it.next();
                if(o.getClass().getName().equals("[Ljava.lang.Object;")) {
                    Object oa[] = (Object[]) o;

                    Produkt p = em.find(Produkt.class, oa[1]);
                    int anzahl = (int)(long)oa[0];
                    System.out.println( "### " + p.getName()+ ", Anzahl Bestellungen: " + oa[0] + ", Preis: " + p.getPreis() + ", Gesamtsumme: " + (p.getPreis()*anzahl));
                }     
            }
        } catch (Exception e) {
            System.out.println("### Fehler: " + e.getMessage());
        }
    }

    
    
    public void nieBestellteProdukte() {
        String s = "SELECT p FROM Produkt p WHERE p.prId NOT IN (SELECT po.prId FROM Posten po)";
        
        try {
            Query query = em.createQuery(s);
            Collection result = query.getResultList();
            
            
            Iterator it = result.iterator();
            while( it.hasNext() ){
                System.out.println( it.next() );
            }
        } catch (Exception e) {
            System.out.println("### Fehler: " + e.getMessage());
        }
    }

    
    
    public void bestellsummenBerechnen() {
        String s = "SELECT b.bKunde, p.poId, p.prId, p.poAnzahl FROM Posten p, Bestellung b WHERE p.bestellung = b";
        

        HashMap<String, Integer> summen = new HashMap<>();
        
        try {
            Query query = em.createQuery(s);
            Collection erg = query.getResultList();
            for (Iterator it = erg.iterator(); it.hasNext();) {
                Object o = it.next();
                if(o.getClass().getName().equals("[Ljava.lang.Object;")) {
                    Object oa[] = (Object[]) o;
                    String kunde    = (String)oa[0];
                    int produkt     = (int) oa[2];
                    int anzahl      = (int) oa[3];
                    
                    int preis;
                    if(summen.containsKey(kunde)) {
                        Produkt p = em.find(Produkt.class, produkt);
                        preis = summen.get(kunde);
                        preis  += anzahl * p.getPreis();
                        
                        summen.remove(kunde);
                        summen.put(kunde, preis);                        
                    } 
                    else {
                        Produkt p = em.find(Produkt.class, produkt);
                        preis = (int)(anzahl * p.getPreis());
                        summen.put(kunde, preis);
                    }
                }
            }
            
            for(String kunde : summen.keySet()) {
                System.out.print("### Kunde: " + kunde + " - ");
                System.out.print("Wert: " + summen.get(kunde) + "\n");
			}
            
        } catch (Exception e) {
            System.out.println("### Fehler: " + e.getMessage());
        }
                
    }

    
    
    void startdaten() {     
       produktAnlegen("Teddy", 10);
       produktAnlegen("Uhr", 50);
       produktAnlegen("Schuhe", 20);
       produktAnlegen("Unbeliebter_Hut", 20);

       
       
       Bestellung b1 = new Bestellung("Hans");
       persist(b1);
       produktInBestellungErgaenzen(b1.getBestellungsNummer(), 1, 2);
       produktInBestellungErgaenzen(b1.getBestellungsNummer(), 2, 1);
       
       Bestellung b2 = new Bestellung("Willi");
       persist(b2);
       produktInBestellungErgaenzen(b2.getBestellungsNummer(), 2, 2);
       produktInBestellungErgaenzen(b2.getBestellungsNummer(), 3, 10);
       produktInBestellungErgaenzen(b2.getBestellungsNummer(), 3, 5);
    }
    
    

    /* freiwillig
     * Ausfuehrung der Anfrage ql, fuer die eine "normale" Liste von
     * Objekten als Ergebnis erwartet wird. */
    public void anfragen(String ql) {

    }

    /* freiwillig
     * Detailliertere Analyse des Ergebnisses der Anfrage ql, falls
     * Object-Arrays in der Ergebnisliste stehen, werden Elemente der
     * Arrays einzeln ausgegeben. */
    public void anfragen2(String ql) {

    }
}
